package dubbo.learn.transport.mina;

import com.alibaba.fastjson.JSONObject;
import dubbo.learn.common.ProviderHostAndPort;
import dubbo.learn.common.RequestVO;
import dubbo.learn.common.RpcContext;
import dubbo.learn.common.contract.transport.TransportLayerRpcInvoker;
import org.apache.dubbo.remoting.transport.mina.MinaClient;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class MinaClientRpcInvoker implements TransportLayerRpcInvoker {

    CustomMinaClient minaClient;

    public static ConcurrentHashMap<String, CompletableFuture<Object>> requestId2futureMap;

    @Override
    public Object invoke(ProviderHostAndPort providerHostAndPort, RpcContext rpcContext) {
        if (minaClient == null) {
            minaClient = new CustomMinaClient(providerHostAndPort);
            requestId2futureMap = rpcContext.getRequestId2futureMap();
        }

        Method method = rpcContext.getMethod();
        if (!method.getName().equals("refreshLocation")) {
            return "";
        }


        RequestVO requestVO = assemblyMessageContent(rpcContext);

        minaClient.send(JSONObject.toJSONString(requestVO));

        return null;
    }




    public static RequestVO assemblyMessageContent(RpcContext rpcContext) {
        RequestVO vo = new RequestVO();

        Object[] args = rpcContext.getArgs();
        if (args != null && args.length > 0) {
            ArrayList<String> paramsJsonArray = new ArrayList<>();
            for (Object arg : args) {
                paramsJsonArray.add(JSONObject.toJSONString(arg));
            }
            vo.setParamsJsonArray(paramsJsonArray);
            vo.setParamCount(args.length);
        } else {
            vo.setParamCount(0);
        }

        vo.setRequestId(rpcContext.getRequestId());
        vo.setServiceName(rpcContext.getServiceName());
        vo.setMethodName(rpcContext.getMethod().getName());

        return vo;
    }
}
